package com.gmscosmo.sdk;

import com.alibaba.fastjson.JSONObject;
import com.gmscosmo.common.APIPath;
import com.gmscosmo.common.IMResult;
import com.gmscosmo.request.ConfigureBody;
import com.gmscosmo.request.CreateRoomBody;
import com.gmscosmo.request.JoinBody;
import com.gmscosmo.request.Jsep;

/**
 * @author stephen.qiu
 */
public class AVEngineKit {
    /**
     * MAIN_PARAMETER:
     *     String description 房间的描述信息
     *     Boolean is_is_private :  true | false（是否是私有房间? 如果创建的是私有房间，则无法通过list指令进行查看）
     *     String secret :  <可选项，操作房间所需的密码，如果设置了，则像做销毁房间这样的操作时你要带上它才行>
     *     String pin :   <可选项，加入会议房间的密码>
     *     Boolean require_pvtid :  true | false（是否订阅音视频流时，需要提供一个与发布者相关的有效_id， 默认为false）
     *     Integer publishers :  <房间内发布者的最大数>（例如，一个视频会议可以有6个发布者，而广播只有一个，默认= 3）
     *     String bitrate : <房间里发布者发送数据的最大比特率>（例如128000）
     *     Integer fir_freq : <向发布者发送FIR指令的频率>（0 =禁用）
     *     String audiocodec : opus | g722 | pcmu | pcma | isac32 | isac16（发布者可以使用的音频编解码器列表，默认为opus。编码器按优先顺序以逗号分隔）
     *     String videocodec : vp8 | vp9 | h264 | av1 | h265（发布者可以使用的视频编解码器列表，默认为vp8。可以按优先级顺序用逗号分隔，例如，vp9，vp8，h264）
     *     String vp9_profile : VP9首选的profile("2" 表示 "profile-id= 2" ）
     *     String h264_profile : H.264首选的profile（"42e01f" 表示 "profile-level-id= 42e01f" ）
     *     Boolean opus_fec : true | false（是否使用带内FEC；仅适用于Opus，默认为false）
     *     Boolean video_svc : true | false（是否启用SVC支持；仅适用于VP9，默认为false）
     *     Boolean audiolevel_ext : true | false（对于发布者是否使用RTP扩展ssrc-audio-level？默认为 true）
     *     Boolean audiolevel_event : true | false（是否将audiolevel事件发送给其他用户）
     *     Integer audio_active_packets : 100（音频保活包个数，默认值= 100，2秒）
     *     Integer audio_level_average : 25（音频音量级别的平均值，127 =静音，0 ='太大声'，默认= 25）
     *     Boolean videoorient_ext = false : true | false（发布者是否使用RTP扩展video-orientation? 默认= true）
     *     Boolean playoutdelay_ext : true | false（发布者是否使用RTP扩展playout-delay? 默认= true）
     *     Boolean transport_wide_cc_ext : true | false（发布者是否使用RTP扩展 transport-wide-cc? 默认= true）
     *     Boolean record : true | false（该房间是否启录制？默认= false）
     *     String rec_dir : <启用录制后，录制文件存放的目录>
     *     Boolean lock_record : true | false（是否锁定录制状态? 默认= false）
     *     Boolean notify_joining : true | false（可选，当有新的参与方加入房音后，是否通知房间里的所有参与者?Videoroom插件默认仅通知发布者，启用此功能可能会导致额外的通知传输。该功能与require_pvtid一起启用时，对管理员管理仅收听的参与者特别有用。默认= false）
     *     Boolean require_e2ee : true | false（是否启用端到端加密? 默认= false）
     *     Boolean permanent : <true | false，是否创建永久房间，默认= false>
     *     String allowed : [可选，用户加入房间的token数组]
     *     Boolean is_public : 是否公开
     * EXAMPLE:
      {
       "createRoomBody":{
           "room":999991,
           "is_":true,
           "pin":"123456",
           "publishers":9
       },
       "userId":"stephen"
      }
     */
    public static IMResult<String> handleCreateRoom(String userId, CreateRoomBody createRoomBody) throws Exception {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userId", userId);
        jsonObject.put("createRoomBody", createRoomBody);
        String path = APIPath.CREATE_ROOM;
        return JanusHttpUtils.httpJsonPost(path, jsonObject, String.class);
    }
    /**
     * MAIN_PARAMETER:
     *     String ptype : 加入类型publisher or subscriber
     *     String pin : 密码
     *     String display : 加入者身份标识
     *     Long feed : 当作为subscriber加入时候，需要提供feed来订阅音视频
     *     String token :  "<invitation token, in case the room has an ACL; optional>"
     * EXAMPLE:
      {
       "joinBody":{
           "ptype":"publisher",
           "pin":"123456",
           "room":999991,
           "display":"stephen"
       },
       "userId":"stephen"
      }
     */
    public static IMResult<String> handleJoinPub(String userId, JoinBody joinBody) throws Exception {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userId", userId);
        jsonObject.put("joinBody", joinBody);
        String path = APIPath.JOIN_PUB;
        return JanusHttpUtils.httpJsonPost(path, jsonObject, String.class);
    }

    /**
     * MAIN_PARAMETER:
     *     Boolean audio : 是否发送音频
     *     Boolean video : 是否发送视频
     *     Integer pin : 密码
     *     Integer substream : substream（0-2）：数字越大分辨率越高
     *     Integer temporal : temporal（0-2）：数字越大帧率越高
     *     Integer spatial_layer :  <spatial layer to receive (0-1), in case VP9-SVC is enabled; optional>,
     *     Integer temporal_layer : <temporal layers to receive (0-2), in case VP9-SVC is enabled; optional>
     *     Integer bitrate : 最大码率,不设置着为无上限
     *     Boolean restart : 重新协商offer
     *     boolean keyframe :  <true|false, whether we should send this publisher a keyframe request>
     *     boolean record :  <true|false, whether this publisher should be recorded or not; optional>,
     *     String filename :  <if recording, the base path/file to use for the recording files; optional>",
     *     String display : <new display name to use in the room; optional>",
     *     String audio_active_packets : <new audio_active_packets to overwrite in the room one; optional>",
     *     String audio_level_average : <new audio_level_average to overwrite the room one; optional>",
     *     Integer mid : <mid of the m-line to refer to for this configure request; optional>,
     *     boolean send : <true|false, depending on whether the media addressed by the above mid should be relayed or not; optional>,
     * EXAMPLE:
      {
       "configureBody":{
           "audio":true,
           "pin":"123456",
           "request":"configure",
           "video":true
       },
       "jsep":{
           "sdp":"v=0\r\no=- 8960238441194795609...",
           "type":"offer"
       },
       "userId":"stephen"
      }
     */
    public static IMResult<String> handleOffer(String userId, Jsep jsep, ConfigureBody configureBody) throws Exception {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userId", userId);
        jsonObject.put("jsep", jsep);
        jsonObject.put("configureBody", configureBody);
        String path = APIPath.OFFER;
        return JanusHttpUtils.httpJsonPost(path, jsonObject, String.class);
    }

    /**
     * MAIN_PARAMETER:
     *     Boolean audio : 是否发送音频
     *     Boolean video : 是否发送视频
     *     Integer pin : 密码
     *     Integer substream : substream（0-2）：数字越大分辨率越高
     *     Integer temporal : temporal（0-2）：数字越大帧率越高
     *     Integer spatial_layer :  <spatial layer to receive (0-1), in case VP9-SVC is enabled; optional>,
     *     Integer temporal_layer : <temporal layers to receive (0-2), in case VP9-SVC is enabled; optional>
     *     Integer bitrate : 最大码率,不设置着为无上限
     *     Boolean restart : 重新协商offer
     *     boolean keyframe :  <true|false, whether we should send this publisher a keyframe request>
     *     boolean record :  <true|false, whether this publisher should be recorded or not; optional>,
     *     String filename :  <if recording, the base path/file to use for the recording files; optional>",
     *     String display : <new display name to use in the room; optional>",
     *     String audio_active_packets : <new audio_active_packets to overwrite in the room one; optional>",
     *     String audio_level_average : <new audio_level_average to overwrite the room one; optional>",
     *     Integer mid : <mid of the m-line to refer to for this configure request; optional>,
     *     Boolean send : <true|false, depending on whether the media addressed by the above mid should be relayed or not; optional>,
     * EXAMPLE:
      {
       "configureBody":{
          "substream":0,
          "temporal":1
       },
       "targetUserId":"targetUserId",
       "userId":"stephen"
      }
     */
    public static IMResult<String> handleConfigure(String userId, String targetUserId, ConfigureBody configureBody) throws Exception {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userId", userId);
        jsonObject.put("targetUserId", targetUserId);
        jsonObject.put("configureBody", configureBody);
        String path = APIPath.CONFIGURE;
        return JanusHttpUtils.httpJsonPost(path, jsonObject, String.class);
    }

    /**
      {
       candidate":"{
           "candidate":"candidate:547260449 1 udp 2122260223 10.0.2.15 38953 typ host generation 0 ufrag kT2l network-id 3 network-cost 10",
           "pin":"123456",
           "sdpMLineIndex":0,
           "sdpMid":"audio"
       }",
       "userId":"stephen",
       "targetUserId":"targetUserId"
     }
     */
    public static IMResult<String> handleCandidate(String userId, String targetUserId,String candidate) throws Exception {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userId", userId);
        jsonObject.put("targetUserId", targetUserId);
        jsonObject.put("candidate", candidate);
        String path = APIPath.TRICKLE;
        return JanusHttpUtils.httpJsonPost(path, jsonObject, String.class);
    }

    /**
     * {
     *     "userId":"stephen"
     * }
     */
    public static IMResult<String> handleKeepALive(String userId) throws Exception {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userId", userId);
        String path = APIPath.KEEP_A_LIVE;
        return JanusHttpUtils.httpJsonPost(path, jsonObject, String.class);
    }

    /**
     * MAIN_PARAMETER:
     *     String pin : 密码
     *     String token :  "<invitation token, in case the room has an ACL; optional>"
     * EXAMPLE:
      {
          "joinBody":{
              "pin":"123456"
          },
          "userId":"stephen",
          "targetUserId":"targetUserId"
      }
     */
    public static IMResult<String> handleJoinAndSub(String userId, String targetUserId, JoinBody joinBody) throws Exception {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userId", userId);
        jsonObject.put("targetUserId", targetUserId);
        jsonObject.put("joinBody", joinBody);
        String path = APIPath.JOIN_SUB;
        return JanusHttpUtils.httpJsonPost(path, jsonObject, String.class);
    }

    /**
      {
       "jsep":{
           "sdp":"v=0\r\no=- 3949792525869817657...",
           "type":"answer"
        },
        "userId":"stephen",
        "targetUserId":"Alice"
      }
     */
    public static IMResult<String> handleStart(String userId, String targetUserId, Jsep jsep) throws Exception {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userId", userId);
        jsonObject.put("jsep", jsep);
        jsonObject.put("targetUserId",targetUserId);
        String path = APIPath.START;
        return JanusHttpUtils.httpJsonPost(path, jsonObject, String.class);
    }

    /**
      {
          "userId":"stephen"
      }
     */
    public static IMResult<String> handleLeave(String userId) throws Exception {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userId", userId);
        String path = APIPath.LEAVE;
        return JanusHttpUtils.httpJsonPost(path, jsonObject, String.class);
    }


    /**
     {
     "userId":"stephen"
     }
     */
    public static IMResult<String> handleStartLive(String userId) throws Exception{
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userId", userId);
        String path = APIPath.START_LIVE;
        return JanusHttpUtils.httpJsonPost(path, jsonObject, String.class);
    }

    /**
     {
     "userId":"stephen"
     }
     */
    public static IMResult<String> handleStopLive(String userId) throws Exception{
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userId", userId);
        String path = APIPath.STOP_LIVE;
        return JanusHttpUtils.httpJsonPost(path, jsonObject, String.class);
    }

    /**
     {
     "userId":"stephen"
     "roomId":123456
     }
     */
    public IMResult<String> handleWatchLive(String userId,int roomId)throws Exception{
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userId", userId);
        jsonObject.put("roomId", roomId);
        String path = APIPath.WATCH_LIVE;
        return JanusHttpUtils.httpJsonPost(path, jsonObject, String.class);
    }
}

